package com.angus.auth.service.front;

import cn.hutool.core.text.CharSequenceUtil;
import com.angus.api.front.RemoteFrontUserService;
import com.angus.api.front.domain.FrontUser;
import com.angus.api.front.model.FrontLoginUser;
import com.angus.api.front.model.FrontUserStatistics;
import com.angus.auth.form.front.PasswordRestBody;
import com.angus.auth.form.front.DeviceLoginBody;
import com.angus.auth.form.front.RegisterBody;
import com.angus.auth.service.CheckService;
import com.angus.common.core.constant.Constants;
import com.angus.common.core.constant.SecurityConstants;
import com.angus.common.core.domain.R;
import com.angus.common.core.enums.SendCodeScene;
import com.angus.common.core.enums.UserStatus;
import com.angus.common.core.exception.ServiceException;
import com.angus.common.core.utils.DateUtils;
import com.angus.common.core.utils.MessageUtils;
import com.angus.common.core.utils.ip.IpUtils;
import com.angus.common.security.utils.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @author liyanan
 * @date 2024/10/14 4:17 PM
 * @description
 */
@Component
public class FrontLoginService {

    private static final Logger log = LoggerFactory.getLogger(FrontLoginService.class);

    @Autowired
    private FrontRecordLogService recordLogService;

    @Autowired
    private CheckService checkService;

    @Resource
    private RemoteFrontUserService remoteFrontUserService;

    @Resource
    private FrontPasswordService passwordService;

    @Resource
    private SendCodeService sendCodeService;

    public FrontLoginUser login(String username, String password) {

        checkService.checkLogin(username, password);
        // 查询用户信息
        R<FrontLoginUser> userResult = remoteFrontUserService.getUserInfo(username, SecurityConstants.INNER);

        if (R.FAIL == userResult.getCode()) {
            throw new ServiceException(userResult.getMsg());
        }

        FrontLoginUser userInfo = userResult.getData();
        FrontUser user = userResult.getData().getFrontUser();
        if (Objects.isNull(user)) {
            recordLogService.recordLoginInfo(username, Constants.LOGIN_FAIL, "对不起，您的账号已被删除");
            throw new ServiceException("对不起，您的账号：" + username + " 已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            recordLogService.recordLoginInfo(username, Constants.LOGIN_FAIL, "用户已停用，请联系管理员");
            throw new ServiceException("对不起，您的账号：" + username + " 已停用");
        }
        passwordService.validate(user, password);
        recordLogService.recordLoginInfo(username, Constants.LOGIN_SUCCESS, "登录成功");
        recordLoginInfo(user.getUserId());
        return userInfo;
    }

    public void logout(String loginName) {
        recordLogService.recordLoginInfo(loginName, Constants.LOGOUT, "退出成功");
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId) {
        FrontUser frontUser = new FrontUser();
        frontUser.setUserId(userId);
        // 更新用户登录IP
        frontUser.setLoginIp(IpUtils.getIpAddr());
        // 更新用户登录时间
        frontUser.setLoginDate(DateUtils.getNowDate());
        remoteFrontUserService.recordUserLogin(frontUser, SecurityConstants.INNER);
    }

    public void register(RegisterBody registerBody) {

        checkService.checkRegister(registerBody.getUsername(), registerBody.getPassword());

        // 注册用户信息
        FrontUser frontUser = new FrontUser();
        frontUser.setUserName(registerBody.getUsername());
        frontUser.setPassword(SecurityUtils.encryptPassword(registerBody.getPassword()));
        R<?> registerResult = remoteFrontUserService.registerUserInfo(frontUser, SecurityConstants.INNER);

        if (R.FAIL == registerResult.getCode()) {
            throw new ServiceException(registerResult.getMsg());
        }
        recordLogService.recordLoginInfo(registerBody.getUsername(), Constants.REGISTER, "注册成功");
    }

    public Boolean sendSendCode(DeviceLoginBody deviceLoginBody) {
        // 如果是绑定的场景则直接发送验证码
        if (!Objects.equals(deviceLoginBody.getScene(), SendCodeScene.MEBER_BIND.getSceneCode())) {
            //验证用户是否存在
            R<FrontLoginUser> result = remoteFrontUserService.selectUserByDevice(deviceLoginBody.getDevice(), deviceLoginBody.getType(), SecurityConstants.INNER);
            // 如果是用户修改手机或邮箱，则不验证用户信息
            if (Objects.equals(deviceLoginBody.getScene(), SendCodeScene.MEMBER_UPDATE.getSceneCode())){
                if (R.SUCCESS == result.getCode()) {
                    throw new ServiceException("该邮箱或手机号已被注册");
                }
            }else {
                if (R.FAIL == result.getCode()) {
                    throw new ServiceException(result.getMsg());
                }

                if (Objects.isNull(result.getData())) {
                    throw new ServiceException(MessageUtils.message("user.not.exist"));
                }
            }
        }
        sendCodeService.sendSendCode(deviceLoginBody.getDevice(), deviceLoginBody.getType(), deviceLoginBody.getScene());
        return Boolean.TRUE;
    }

    public FrontLoginUser sendCodeLogin(DeviceLoginBody deviceLoginBody) {

        boolean b = sendCodeService.checkSendCode(deviceLoginBody.getDevice(), deviceLoginBody.getCode(), SendCodeScene.MEMBER_LOGIN);
        FrontLoginUser userInfo = new FrontLoginUser();
        if (b) {
            R<FrontLoginUser> userResult = remoteFrontUserService.selectUserByPhoneNum(deviceLoginBody.getDevice(), SecurityConstants.INNER);
            if (R.FAIL == userResult.getCode()) {
                throw new ServiceException(userResult.getMsg());
            }
            userInfo = userResult.getData();
            recordLogService.recordLoginInfo(userInfo.getUsername(), Constants.LOGIN_SUCCESS, "登录成功");
            recordLoginInfo(userInfo.getFrontUser().getUserId());
        }
        return userInfo;
    }

    public boolean checkSendCode(DeviceLoginBody deviceLoginBody) {
        return sendCodeService.checkSendCode(
                deviceLoginBody.getDevice(),
                deviceLoginBody.getCode(),
                Objects.requireNonNull(SendCodeScene.getCodeBySceneCode(deviceLoginBody.getScene()))
        );
    }

    public void resetPassword(PasswordRestBody passwordRestBody) {
        FrontLoginUser userInfo = new FrontLoginUser();
        if (CharSequenceUtil.isBlank(passwordRestBody.getEmail()) && CharSequenceUtil.isBlank(passwordRestBody.getPhoneNumber())) {
            throw new ServiceException("请输入邮箱或手机号");
        }

        if (CharSequenceUtil.isNotBlank(passwordRestBody.getEmail())) {
            boolean b = sendCodeService.checkSendCode(passwordRestBody.getEmail(), passwordRestBody.getCode(),SendCodeScene.MEBER_FORGET_PASSWORD);
            if (b) {
                R<FrontLoginUser> userResult = remoteFrontUserService.findUserByEmail(passwordRestBody.getEmail(), SecurityConstants.INNER);
                if (R.FAIL == userResult.getCode()) {
                    throw new ServiceException(userResult.getMsg());
                }
                userInfo = userResult.getData();
            }
        } else {
            // 验证验证码
            boolean b = sendCodeService.checkSendCode(passwordRestBody.getPhoneNumber(), passwordRestBody.getCode(),SendCodeScene.MEBER_FORGET_PASSWORD);
            if (b) {
                R<FrontLoginUser> userResult = remoteFrontUserService.selectUserByPhoneNum(passwordRestBody.getPhoneNumber(), SecurityConstants.INNER);
                if (R.FAIL == userResult.getCode()) {
                    throw new ServiceException(userResult.getMsg());
                }
                userInfo = userResult.getData();
            }
        }
        if(userInfo == null) {
            throw new ServiceException("邮箱信息或手机号信息有误");
        }

        FrontUser frontUser = userInfo.getFrontUser();
        if (frontUser != null) {
            frontUser.setPassword(SecurityUtils.encryptPassword(passwordRestBody.getNewPassword()));
            // 更新密码
            log.info("重置密码用户ID：{}, 手机号：{}, 邮箱：{}, 新密码：{}, 加密后的密码：{}", frontUser.getUserId(), frontUser.getPhoneNumber(), frontUser.getUserEmail(), passwordRestBody.getNewPassword(), frontUser.getPassword());
            remoteFrontUserService.passwordRest(frontUser, SecurityConstants.INNER);
        }
    }

    public FrontUserStatistics getUserInfoCount() {
        R<FrontUserStatistics> userInfoCount = remoteFrontUserService.getUserInfoCount(SecurityConstants.INNER);
        return userInfoCount.getData();
    }
}
